package com.nCoV.EpidemicSurveillance.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.neo4j.repository.query.GraphQueryExecution.CountByExecution;
import org.springframework.stereotype.Service;

import com.nCoV.EpidemicSurveillance.common.utils.DateUtil;
import com.nCoV.EpidemicSurveillance.common.utils.MapUtil;
import com.nCoV.EpidemicSurveillance.domain.AreaReach;
import com.nCoV.EpidemicSurveillance.domain.CxArea;
import com.nCoV.EpidemicSurveillance.domain.PatientAreaRelation;
import com.nCoV.EpidemicSurveillance.domain.PatientTrainRelation;
import com.nCoV.EpidemicSurveillance.domain.Person;
import com.nCoV.EpidemicSurveillance.domain.TrainNode;
import com.nCoV.EpidemicSurveillance.repository.AreaRepository;
import com.nCoV.EpidemicSurveillance.repository.PersonRepository;
import com.nCoV.EpidemicSurveillance.repository.TrafficRepository;

import lombok.extern.log4j.Log4j2;

/**
 * @author 罗穆健
 * @date 2020年3月10日
 */
@Service
public class DataEntryService {
	
	@Autowired
	private PersonRepository personRepository;
	
	@Autowired
	private AreaRepository areaRepository;
	
	@Autowired
	private TrafficRepository trafficRepository;
	
	private static final Logger logger = LogManager.getLogger(DataEntryService.class);	
	
	/**
	 * 
	 * @author 罗穆健
	 * @date 2020年3月11日
	 * @param name
	 * @param idCard
	 * @return code 1成功  2数据库操作失败 3输入为空 4身份证已存在
	 */
	public Map<String, Object> createOrQuery(String name, String idCard) {
		Map<String, Object> patientMap = new HashMap<String, Object>();
		if(name==null||name==""||idCard==null||idCard=="") {
			patientMap.put("code","3");
		} else {
			try {
				System.out.println(personRepository.createPerson(name,idCard));
				Person patientPerson = personRepository.createPerson(name,idCard);
				patientMap = MapUtil.objectToMap(patientPerson);	
				System.out.println(patientMap);
				patientMap.put("code","1");
			} catch (Exception e) {
				System.out.println(e);
				if(e instanceof DataIntegrityViolationException) {

					patientMap.put("code","4");
				}else {

					patientMap.put("code","2");
				}
			}
		}	
		return patientMap;

	}
 

	/**
	 * 
	 * @author 罗穆健
	 * @date 2020年3月11日
	 * @param name
	 * @param idCard
	 * @param address
	 * @param email 
	 * @param phone 
	 * @param jcbNum 
	 * @param sex 
	 * @param age 
	 * @param jcNum 
	 * @param grgl 
	 * @param glqk 
	 * @return code 1成功 2数据库操作失败
	 */
	public Map<String, Object> setMsg(String name, String idCard, String address,
			String age, String sex, String jcbNum, String phone, 
			String email, String jcNum, String grgl,String zlqk, String glqk) {
		// TODO Auto-generated method stub
		Map<String, Object> patientMsgMap = new HashMap<String, Object>();
		try {
			personRepository.setPatientMsg(name,idCard,address,age,sex,jcbNum,phone,email,jcNum,grgl,zlqk,glqk);
			patientMsgMap.put("code",1);
		} catch (Exception e) {
			// TODO: handle exception
			logger.info(e);
			patientMsgMap.put("code",2);
		}
		return patientMsgMap;
	}
	/**
	 * 
	 * @author 罗穆健
	 * @date 2020年3月13日
	 * @param patientIdCard
	 * @param contactorName
	 * @param contactorIdCard
	 * @param contactTime
	 * @param kzqk 
	 * @param tfqk 
	 * @param duration 
	 * @param dfkz 
	 * @param relationName
	 * @return code 1成功 2身份证已存在 3数据库操作失败
	 */
	public Map<String, Object> createRelation(String patientIdCard, String contactorName, String contactorIdCard,
			String contactTime, String contactName, String duration, String tfqk, String kzqk, String dfkz) {
		// TODO Auto-generated method stub

		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			personRepository.createContactor(contactorName,contactorIdCard);
			personRepository.createRelation(patientIdCard,contactorName,contactorIdCard,
					contactTime,contactName,duration,tfqk,kzqk,dfkz,DateUtil.getNowDay(),DateUtil.getNowDay());
			codeMap.put("code",1);
		} catch (Exception e) {
			// TODO: handle exception
			if(e instanceof org.neo4j.driver.exceptions.ClientException) {

				codeMap.put("code","2");
			}else {

				codeMap.put("code","3");
			}
		}
		return codeMap;
	}

	/**
	 * 
	 * @author 罗穆健
	 * @date 2020年3月23日
	 * @param patientIdCard
	 * @param limitNum 
	 * @param skipNum 
	 * @return code 1正常 2异常
	 */
	public List<Map<String, Object>> getRelationByIdCard(String patientIdCard, String skipNum, String limitNum,String searchIdCard,String searchName) {
		// TODO Auto-generated method stub
		List<Map<String, Object>> relationList = new ArrayList<Map<String,Object>>();
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			String cxPersonCql = "match(n:Person{idCard:'"+ patientIdCard 
					+"'})-[R:PersonRelation]->(m:Person) "
					+ " where (m.name=~'.*"+ searchName +".*' or m.idCard=~'.*"+ searchIdCard +".*' )"
					+ "and R.sc <> 'true' "
					+ " return R.contactName as contactName,"
					+ " R.contactTime as contactTime,m.idCard as idCard,"
					+ "m.name as name,m.phone as contactorPhone,"
					+ "R.duration as duration,"
					+ "R.tfqk as tfqk,"
					+ "R.kzqk as kzqk,"
					+ "R.dfkz as dfkz,"
					+ "R.createDay as createDay"
					+ " skip " + skipNum
					+ " limit " +  limitNum;
			String countCqlString = "match (r:Person{idCard:'"+ patientIdCard
					+"'}) - [p:PersonRelation]->(m:Person) "
					+ " where m.name=~'.*"+ searchName +".*' or m.idCard=~'.*"+ searchIdCard +".*' "
					+ "and p.sc <> 'true' "
					+ " return count(*) as count";
			relationList = personRepository.queryContactorByRelation(cxPersonCql);
			Map<String,Object> countMap =  personRepository.getPersonCount(countCqlString);
			codeMap.putAll(countMap);
			codeMap.put("code","1");
		} catch (Exception e) {
			logger.info(e);
			codeMap.put("code","2");
		}
		relationList.add(codeMap);
		logger.info(relationList);
		return relationList;
	}
	
	public Map<String, Object> deleteRelationByIdCard(String patientIdCard, String contactorIdCard, String contactName, String createDay){
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			if(DateUtil.getNowDay().equals(createDay)) {
				personRepository.deleteRelationByIdCard(patientIdCard,contactorIdCard,contactName);
			}else {
				personRepository.deleteRelationByIdCardT(patientIdCard,contactorIdCard,contactName);//暂时不删除，通过定时任务删除
			}

			codeMap.put("code","1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code","2");
		}
		
		return codeMap;
	}

	public Map<String, Object> getXqRelationByIdCard(String patientIdCard, String contactorIdCard, String contactName) {
		// TODO Auto-generated method stub
		Map<String, Object> xqMap = new HashMap<String, Object>();
		try {
			xqMap = personRepository.queryXqContactorByRelation(patientIdCard,contactorIdCard,contactName);
			xqMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			xqMap.put("code", "2");
		}
		
		return xqMap;
	}

	public Map<String, Object> addNewArea(AreaReach areaReach, PatientAreaRelation patientAreaRelation
			, String patientIdCard) {
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			areaRepository.addNewArea(areaReach.getAddressName(),areaReach.getXqAddress());
			areaRepository.createPatientAreaRealtion(areaReach,patientAreaRelation,patientIdCard);
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		return codeMap;
	}

	public List<Map<String, Object>> getAreaRelationByIdCard(String patientIdCard, int skipNum, int limitNum,
			String searchAreaData) {
		// TODO Auto-generated method stub
		List<Map<String, Object>> relationList = new ArrayList<Map<String,Object>>();
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			searchAreaData = ".*" + searchAreaData + ".*";
			relationList = areaRepository.queryAreaByRelation(patientIdCard,searchAreaData,skipNum,limitNum);
			int count = areaRepository.getAreaRelationCount(patientIdCard, searchAreaData);
			codeMap.put("code", "1");
			codeMap.put("count", count);
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		relationList.add(codeMap);
		logger.info(relationList);
		return relationList;
	}
	
	public Map<String, Object> deleteAreaRelationByIdCard(String patientIdCard, String addressName, String xqAddress, String contactName){
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			areaRepository.deleteAreaRelationByIdCard(patientIdCard,contactName,addressName,xqAddress);
			codeMap.put("code","1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code","2");
		}
		return codeMap;
	}

	public Map<String, Object> createTrainRelation(String patientIdCard, TrainNode trainNode,
			PatientTrainRelation patientTrainRelation) {
		// TODO Auto-generated method stub
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			trafficRepository.createTrain(trainNode);
			trafficRepository.createTrainRelation(patientIdCard,patientTrainRelation,trainNode.getTrainNumber());
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		return codeMap;
	}

	public List<Map<String, Object>> getTrafficRelation(String patientIdCard, int skipNum, int limitNum,
			String searchTrafficData) {
		// TODO Auto-generated method stub
		List<Map<String, Object>> relationList = new ArrayList<Map<String,Object>>();
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			searchTrafficData = ".*" + searchTrafficData + ".*";
			relationList = trafficRepository.queryAreaByRelation(patientIdCard,searchTrafficData,skipNum,limitNum);
			int count = trafficRepository.getAreaRelationCount(patientIdCard, searchTrafficData);
			codeMap.put("code", "1");
			codeMap.put("count", count);
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		relationList.add(codeMap);
		logger.info(relationList);
		return relationList;
	}

	public Map<String, Object> deleteTrafficRelation(Long relationId) {
		// TODO Auto-generated method stub
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			trafficRepository.deleteTrafficRelation(relationId);
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		return codeMap;
	}

	public Map<String, Object> updatedTraffic(PatientTrainRelation patientTrainRelation, Long trafficId) {
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			trafficRepository.updatedTraffic(patientTrainRelation,trafficId);
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		logger.info("updatedTrafficCode=" + codeMap);
		return codeMap;
	}

	public Map<String, Object> updateArea(Long areaId, Long relationId, String addressName, String xqAddress,
			String reachTime, String leaveTime, String tfqk, String kzqk) {
		// TODO Auto-generated method stub
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			areaRepository.updateAreaRelation(areaId,relationId,reachTime,leaveTime,addressName,xqAddress,tfqk,kzqk);
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		return codeMap;
	}

	public Map<String, Object> updatePerson(String patientIdCard, String contactorIdCard, String contactName,
			String contactTime, String contactorPhone, String duration, String tfqk, String kzqk, String dfkz) {
		// TODO Auto-generated method stub
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			personRepository.updatePerson(patientIdCard,contactorIdCard,contactName,contactTime,contactorPhone,
					duration,tfqk,kzqk,dfkz,DateUtil.getNowDay());
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		return codeMap;
	}


	public Map<String, Object> deleteNode(Long id) {
		// TODO Auto-generated method stub
		Map<String, Object> codeMap = new HashMap<String, Object>();
		try {
			personRepository.deleteNode(id);
			codeMap.put("code", "1");
		} catch (Exception e) {
			// TODO: handle exception
			codeMap.put("code", "2");
		}
		return codeMap;
	}

}
